# -*- coding: utf-8 -*-
import json

from django.views.decorators.http import require_GET, require_POST

from common.cache import redis_cache
from common.channel import db
from common.level_strategy import db as level_db
from common.mch import handler as mch_handler
from common.mch.admin_db import get_mch_chns
from common.order.mg_stat import check_user_pay_count_is_over_limist
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils import tz
from common.utils.api import check_params
from common.utils.decorator import response_wrapper

_LOGGER = track_logging.getLogger(__name__)


def _check_channel_is_risk(channel_id, chn_info):
    # 检查累积充值风控
    try:
        # _LOGGER.info('check _check_channel_is_risk channel_id:%s, chn_info: %s ', channel_id, chn_info)
        if 'incr_risk' in chn_info:
            daily_stats, hourly_stats, minutely_stats = redis_cache.get_chn_amount(channel_id)
            risk_conf = chn_info['incr_risk']
            if 'daily' in risk_conf:
                daily_conf = risk_conf['daily']
                amount, count = daily_conf.get('amount', 0), daily_conf.get('count', 1000000)
                if amount == 0 or int(daily_stats.get('amount', 0)) >= amount:
                    raise err.ReachLimit('chn reached daily amount limit, %s' % channel_id)
                if count and int(daily_stats.get('count', 0)) >= count:
                    raise err.ReachLimit('chn reached daily count limit, %s' % channel_id)
            if 'hourly' in risk_conf:
                hourly_conf = risk_conf['hourly']
                amount, count = hourly_conf.get('amount', 0), hourly_conf.get('count', 1000000)
                if amount == 0 or int(hourly_stats.get('amount', 0)) >= amount:
                    raise err.ReachLimit('chn reached hourly amount limit, %s' % channel_id)
                if count and int(hourly_stats.get('count', 0)) >= count:
                    raise err.ReachLimit('chn reached hourly count limit, %s' % channel_id)
            if 'minutely' in risk_conf:
                minutely_conf = risk_conf['minutely']
                count = minutely_conf.get('count', 1000000)
                if count and int(minutely_stats.get('count', 0)) >= count:
                    raise err.ReachLimit('chn reached minutely count limit, %s' % channel_id)
    except Exception as e:
        _LOGGER.warn('check incr_risk warn, %s', e)
        return True
    return False


def _check_channel_daily_vaild_time(chn_info):
    try:
        if 'daily_open_time' in chn_info:
            daily_open_time = chn_info['daily_open_time']
            start = daily_open_time.get('start', 0)
            end = daily_open_time.get('end', 24)
            hour = tz.local_now().hour
            if start > end:  # 跨日
                if hour > end:
                    end += 24
                else:
                    end += 24
                    hour += 24
            if hour < start or hour >= end:
                return True
    except Exception as e:
        _LOGGER.exception('_check_channel_daily_vaild_time exceptions, %s', e)
        return False
    return False


def update_limist_amount(chn, restult):
    info = json.loads(chn.info)
    min = info.get('min_amount', 0)
    max = info.get('max_amount', 10000)
    if chn.service_name == 'recharge_card':
        return
    if restult.get(chn.service_name) is None:
        restult[chn.service_name] = {}
        restult[chn.service_name]['min'] = min
        restult[chn.service_name]['max'] = max
    else:
        restult[chn.service_name]['min'] = min if min < restult[chn.service_name]['min'] else restult[chn.service_name][
            'min']
        restult[chn.service_name]['max'] = max if max > restult[chn.service_name]['max'] else restult[chn.service_name][
            'max']


@require_POST
@response_wrapper
def get_vaild_chns_type_by_mch(request):
    params = request.POST.dict()
    check_params(params, ['mch_id', 'sign'], param_type_dct={
        'mch_id': basestring,
    })
    sign = params['sign']
    params.pop('sign')
    mch_id = params['mch_id']
    calculated_sign = mch_handler.generate_sign(mch_id, params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')
    channels = db.get_mch_available_channels(mch_id)
    m_sel_channels = get_mch_chns(mch_id)
    quotas = []
    wx_quotas = []
    hydra_quotas = []
    types = []
    types_limist = {}
    for chn in channels:
        if _check_channel_daily_vaild_time(json.loads(chn.info)):
            continue
        if _check_channel_is_risk(chn.id, json.loads(chn.info)):
            continue
        if str(chn.id) not in m_sel_channels:
            continue
        user_id = params.get('user_id')
        level_strategy = level_db.get_vaild_user_level_strategy_by_mch_id(int(mch_id))
        if user_id is not None and check_user_pay_count_is_over_limist(mch_id, user_id, chn.id):
            continue
        if user_id and level_strategy:
            chn_level = level_db.get_mch_user_channel_level(mch_id, user_id)
            if not chn_level and chn.levels:
                continue
            if chn_level and chn.levels and chn.levels != '' \
                    and int(chn_level) not in [int(x) for x in chn.levels.split(',')]:
                continue
        if chn.service_name == 'quota_alipay':
            for q in [float(y) for y in chn.quotas.split(',')]:
                if q not in quotas:
                    quotas.append(q)
        elif chn.service_name == 'quota_wxpay':
            for q in [float(y) for y in chn.quotas.split(',')]:
                if q not in wx_quotas:
                    wx_quotas.append(q)
        elif chn.service_name == 'quota_hydra':
            for q in [float(y) for y in chn.quotas.split(',')]:
                if q not in hydra_quotas:
                    hydra_quotas.append(q)
        else:
            update_limist_amount(chn, types_limist)
        if chn.service_name not in types:
            types.append(chn.service_name)
    return {'list': types, 'quotas': quotas, 'wx_quotas': wx_quotas, 'hydra_quotas': hydra_quotas, 'types_limist': types_limist}


@require_GET
@response_wrapper
def copy_channel(request):
    params = request.GET.dict()
    db.channel_copy(int(params['channel_id']))
    return {'msg': 'succeess'}
